package com.amos.util;

import com.amos.core.BaseDTO;
import com.amos.core.BaseEntity;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Copyright © 2018 嘉源锐信. All rights reserved.
 *
 * @Project: mu-exam
 * @ClassName: PropertiesCopyUtils
 * @Package: com.amos.util
 * @author: zhuqb
 * @Description: 属性复制
 * @date: 2020/3/4 0004 下午 17:38
 * @Version: V1.0
 */
public class PropertiesCopyUtils {
    /**
     * DTO 转 Entity对象
     *
     * @param dto         DTO对象
     * @param entityClazz Entity的Class对象
     * @param <T>
     * @param <E>
     * @return
     */
    public static <T extends BaseDTO, E extends BaseEntity> E dto2Entity(T dto, Class<E> entityClazz) {
        return (E) copryProperties(dto, entityClazz, true);
    }

    /**
     * @param entity   Entity对象
     * @param dtoClass DTO的Class对象
     * @param <T>
     * @param <E>
     * @return
     */
    public static <T extends BaseDTO, E extends BaseEntity> T entity2Dto(E entity, Class<T> dtoClass) {
        return (T) copryProperties(entity, dtoClass, true);
    }

    /**
     * TODO
     *
     * @param entities
     * @param dtoClass
     * @param <T>
     * @param <E>
     * @return
     */
    public static <T extends BaseDTO, E extends BaseEntity> List<T> entities2Dtos(List<E> entities, Class<T> dtoClass) {
        return null;
    }

    /**
     * 对象转换赋值(是否赋值控制)
     *
     * @param source                 来源对象
     * @param destClazz              目标Class类
     * @param isContainsEmptyElement 是否包含控制
     * @return
     */
    public static Object copryProperties(Object source, Class<?> destClazz, boolean isContainsEmptyElement) {
        try {
            Object object = destClazz.newInstance();
            if (isContainsEmptyElement) {
                BeanUtils.copyProperties(source, object);
            } else {
                BeanUtils.copyProperties(source, object, getNullPropertyNames(source));
            }
            return object;
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 过滤空值
     *
     * @param source
     * @return
     */
    public static String[] getNullPropertyNames(Object source) {
        final BeanWrapper src = new BeanWrapperImpl(source);
        java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();

        Set<String> emptyNames = new HashSet<String>();
        for (java.beans.PropertyDescriptor pd : pds) {
            Object srcValue = src.getPropertyValue(pd.getName());
            if (srcValue == null) {
                emptyNames.add(pd.getName());
            }
        }
        String[] result = new String[emptyNames.size()];
        return emptyNames.toArray(result);
    }
}
